﻿package
{
	import flash.display.Sprite;
	import flash.utils.Timer;
	import flash.events.TimerEvent;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.text.TextField;
	
	public class Main extends Sprite
	{
		//jjj
		// 一个2维数组用来存储游戏区块
		//
		private var plantsArray:Array; // 种植在游戏区域里的植物
		private var zombiesArray:Array; //在游戏区域里的僵尸
		// 
		// 计时器
		//
		private var flowersTimer:Timer = new Timer(5000); //计时器，使得阳光落下
		private var zombieTimer:Timer = new Timer(5000); // 计时器，让僵尸出场
		//
		// 容器
		//
		private var sunContainer:Sprite = new Sprite(); // 所有阳光的容器
		private var plantContainer:Sprite = new Sprite(); // 所有植物的容器
		public var bulletContainer:Sprite = new Sprite(); // 所有子弹的容器
		private var zombieContainer:Sprite = new Sprite(); // 所有僵尸的容器
		private var overlayContainer:Sprite = new Sprite(); // 所有覆盖物的容器
		//
		// 我们的演员
		//
		private var movingPlant:plantMc; //  玩家在游戏区域能够拖动的植物
		private var selector:selectorMc; // 选择器（一个高亮的区块），告诉玩家他将把植物种在哪
		//
		// 其它变量
		//
		private var money:uint = 0; // 玩家所拥有的金钱数量
		private var moneyText:TextField = new TextField; // 动态文本框，用来显示玩家的金钱
		private var playerMoving:Boolean = false; // 布尔型变量，标志玩家是否在移动一个植物
		private var totalZombies:uint = 0; //僵尸的总数
		
		public function Main():void
		{
			setupField(); //初始化游戏区块
			drawField(); //画出游戏区块
			fallingSuns(); // 初始化下落的阳光
			addPlants(); // 初始化植物
			addZombies(); //初始化僵尸
			addEventListener(Event.ENTER_FRAME, onEnterFrm);
		}
		
		//
		//  游戏区域设置，创建用来存储植物和僵尸信息的数组
		//
		private function setupField():void
		{
			plantsArray = new Array();
			zombiesArray = new Array();
			for (var i:uint = 0; i < 5; i++)
			{
				plantsArray[i] = new Array();
				zombiesArray[i] = new Array();
				for (var j:uint = 0; j < 9; j++)
				{
					plantsArray[i][j] = 0;
				}
			}
		}
		
		//
		// 显示玩家的金钱
		//
		private function updateMoney():void
		{
			moneyText.text = "Money: " + money.toString();
		}
		
		//
		// 画出游戏区域
		//
		private function drawField():void
		{
			var fieldSprite:Sprite = new Sprite();
			var randomGreen:Number;
			addChild(fieldSprite);
			fieldSprite.graphics.lineStyle(1, 0xFFFFFF);
			for (var i:uint = 0; i < 5; i++)
			{
				for (var j:uint = 0; j < 9; j++)
				{
					randomGreen = (125 + Math.floor(Math.random() * 50)) * 256;
					fieldSprite.graphics.beginFill(randomGreen);
					fieldSprite.graphics.drawRect(25 + 65 * j, 80 + 75 * i, 65, 75);
				}
			}
			addChild(sunContainer);
			addChild(plantContainer);
			addChild(bulletContainer);
			addChild(zombieContainer);
			addChild(overlayContainer);
			overlayContainer.addChild(moneyText);
			updateMoney();
			moneyText.textColor = 0xFFFFFF;
			moneyText.height = 20;
		}
		
		//
		// 初始化僵尸
		//
		private function addZombies():void
		{
			zombieTimer.start();
			zombieTimer.addEventListener(TimerEvent.TIMER, newZombie);
		}
		
		//
		// 增加一个新的僵尸
		//
		private function newZombie(e:TimerEvent):void
		{
			var zombie:zombieMc = new zombieMc(); // 构造僵尸
			totalZombies++;
			zombieContainer.addChild(zombie); // 增加僵尸
			zombie.zombieRow = Math.floor(Math.random() * 5); //生成随机行数，用于放置僵尸
			zombie.name = "zombie_" + totalZombies; //给僵尸一个名字
			zombiesArray[zombie.zombieRow].push(zombie.name); // 增加第row行的僵尸
			zombie.x = 660; // 把僵尸放在屏幕的右边
			zombie.y = zombie.zombieRow * 75 + 115;
		}
		
		//
		// 初始化阳光
		//
		private function fallingSuns():void
		{
			flowersTimer.start();
			flowersTimer.addEventListener(TimerEvent.TIMER, newSun);
		}
		
		//
		// 增加一束新的阳光
		//
		private function newSun(e:TimerEvent):void
		{
			var sunRow:uint = Math.floor(Math.random() * 5); // 随机行
			var sunCol:uint = Math.floor(Math.random() * 9); // 随机列
			var sun:sunMc = new sunMc(); // 构造阳光
			sun.buttonMode = true; // 当鼠标滑过阳光时，改变鼠标的形状
			sunContainer.addChild(sun); // 加入显示列表
			sun.x = 52 + sunCol * 65; // 把阳光放在合适的位置
			sun.destinationY = 130 + sunRow * 75; // 定义阳光destinationY属性
			sun.y = -20; // 把阳光放在舞台顶部的上方
			sun.addEventListener(MouseEvent.CLICK, sunClicked); // 给阳光注册鼠标点击事件
		}
		
		//
		// 阳光的鼠标点击事件句柄
		//
		private function sunClicked(e:MouseEvent):void
		{
			e.currentTarget.removeEventListener(MouseEvent.CLICK, sunClicked); // 移除鼠标事件侦听
			money += 5; //让玩家赚到5个金币
			updateMoney(); // 更新动态文本
			var sunToRemove:sunMc = e.currentTarget as sunMc; // 获得我们必须移除的阳光
			sunContainer.removeChild(sunToRemove); // 移除该阳光
		}
		
		// 创建一个植物栏，现在只有一种植物
		//
		private function addPlants():void
		{
			var plant:plantMc = new plantMc(); // 构造一株新的植物
			overlayContainer.addChild(plant); // 增加植物
			plant.buttonMode = true; // 使鼠标改变形状，当它滑过新植物时
			plant.x = 90;
			plant.y = 40;
			plant.addEventListener(MouseEvent.CLICK, onPlantClicked); // 给新植物注册鼠标点击事件
		}
		
		//
		// 植物的鼠标点击事件句柄
		//
		private function onPlantClicked(e:MouseEvent):void
		{
			// 检查玩家是否有足够的钱（当前是10）来购买植物，并且是否正在拖动一个植物
			if (money >= 10 && !playerMoving)
			{
				money -= 10; // 付款
				updateMoney(); // 更新动态文本
				selector = new selectorMc(); // 创建一个新的选择器
				selector.visible = false; // 使选择器不可见
				overlayContainer.addChild(selector); // 把选择器加入到显示列表
				movingPlant = new plantMc(); // 构建一个新的供玩家拖动的植物
				movingPlant.addEventListener(MouseEvent.CLICK, placePlant); // 给该植物注册一个鼠标点击事件
				overlayContainer.addChild(movingPlant); // 把该植物加入到显示列表
				playerMoving = true; // 告诉脚本正在移动一株植物
			}
		}
		
		//
		// 把植物放置在游戏区域中
		//
		private function placePlant(e:MouseEvent):void
		{
			var plantRow:int = Math.floor((mouseY - 80) / 75);
			var plantCol:int = Math.floor((mouseX - 25) / 65);
			// let's see if the tile is inside the game field and it's free
			if (plantRow >= 0 && plantCol >= 0 && plantRow < 5 && plantCol < 9 && plantsArray[plantRow][plantCol] == 0)
			{
				var placedPlant:plantMc = new plantMc(); // 构建一株植物，用来种植
				placedPlant.name = "plant_" + plantRow + "_" + plantCol; // 给植物一个名字
				placedPlant.fireRate = 75; // 植物的开火速率，单位帧
				placedPlant.recharge = 0; // 当recharge 等于 fireRate时，植物已经准备好开火了
				placedPlant.isFiring = false; // 一个布尔变量来存储植物是否正在开火
				placedPlant.plantRow = plantRow; // 植物所在的行
				plantContainer.addChild(placedPlant); // 把该植物加入到显示列表
				placedPlant.x = plantCol * 65 + 57;
				placedPlant.y = plantRow * 75 + 115;
				playerMoving = false; // 告诉脚本玩家不在移动植物了
				movingPlant.removeEventListener(MouseEvent.CLICK, placePlant); // 移除事件侦听
				overlayContainer.removeChild(selector); // 移除选择器
				overlayContainer.removeChild(movingPlant); // 移除供拖动的植物
				plantsArray[plantRow][plantCol] = 1; //  更新游戏区块信息
			}
		}
		
		//
		// 游戏循环，游戏的核心函数
		//
		private function onEnterFrm(e:Event):void
		{
			var i:int;
			var j:int;
			//
			// 植物管理
			//
			for (i = 0; i < plantContainer.numChildren; i++)
			{
				var currentPlant:plantMc = plantContainer.getChildAt(i) as plantMc;
				// 让我们看看植物是否能开火
				if (currentPlant.recharge == currentPlant.fireRate && !currentPlant.isFiring)
				{
					// 检查是否有僵尸与植物处于同一行
					if (zombiesArray[currentPlant.plantRow].length > 0)
					{
						// 遍历僵尸
						for (j = 0; j < zombiesArray[currentPlant.plantRow].length > 0; j++)
						{
							var targetZombie:zombieMc = zombieContainer.getChildByName(zombiesArray[currentPlant.plantRow]
								
								[j]) as zombieMc; // 获得第j个僵尸
							// 如果僵尸在植物的右边
							if (targetZombie.x > currentPlant.x)
							{
								var bullet:bulletMc = new bulletMc(); // 创建一个新子弹
								bulletContainer.addChild(bullet); // 加入到显示列表
								bullet.x = currentPlant.x;
								bullet.y = currentPlant.y;
								bullet.sonOf = currentPlant; // 存储该子弹是由哪一株植物射出的
								currentPlant.recharge = 0; // 重新准备开火
								currentPlant.isFiring = true; // 植物正在开火
								break; // 终止for循环
							}
						}
					}
				}
				if (currentPlant.recharge < currentPlant.fireRate)
				{
					currentPlant.recharge++;
				}
			}
			//
			// 子弹管理
			//
			for (i = 0; i < bulletContainer.numChildren; i++)
			{
				var movingBullet:bulletMc = bulletContainer.getChildAt(i) as bulletMc;
				movingBullet.x += 3; //把每个子弹向右移动3个像素
				var firingPlant:plantMc = movingBullet.sonOf as plantMc; // 获得这个子弹是哪个植物射击的
				// 让我们看看子弹是否飞出了舞台
				if (movingBullet.x > 650)
				{
					firingPlant.isFiring = false; // 植物不再处于正在开火的状态
					bulletContainer.removeChild(movingBullet); // 移除子弹
				}
				else
				{
					for (j = 0; j < zombieContainer.numChildren; j++)
					{
						var movingZombie:zombieMc = zombieContainer.getChildAt(j) as zombieMc;
						// 让我们看看植物是否被子弹击中
						if (movingZombie.hitTestPoint(movingBullet.x, movingBullet.y, true))
						{
							movingZombie.alpha -= 0.3; //减少僵尸的能量（透明度）
							firingPlant.isFiring = false; // 植物不再处于正在开火的状态
							bulletContainer.removeChild(movingBullet); // 移除子弹
							// 让我们看看僵尸的能量（透明度）是否降至为0了
							if (movingZombie.alpha < 0)
							{
								zombiesArray[movingZombie.zombieRow].splice(zombiesArray[movingZombie.zombieRow].indexOf(movingZombie.name), 1); // 减少该行的僵尸 
								zombieContainer.removeChild(movingZombie); // 移除显示列表
							}
							break;
						}
					}
				}
			}
			//
			// 僵尸管理
			//
			var zombieColumn:int;
			for (i = 0; i < zombieContainer.numChildren; i++)
			{
				movingZombie = zombieContainer.getChildAt(i) as zombieMc;
				zombieColumn = Math.floor((movingZombie.x - 25) / 65); // 得到僵尸所在的列
				// 检查是否有植物与之处于同一个区块
				if (zombieColumn < 0 || zombieColumn > 8 || plantsArray[movingZombie.zombieRow][zombieColumn] == 0)
				{
					movingZombie.x -= 0.5; // 每一个僵尸往左移动0.5个像素
				}
				else
				{
					// 僵尸开始攻击!!
					var attackedPlant:plantMc = plantContainer.getChildByName("plant_" + movingZombie.zombieRow + "_" + zombieColumn) as plantMc;
					attackedPlant.alpha -= 0.01; // drains plant energy
					//检查植物是否死了
					if (attackedPlant.alpha < 0)
					{
						plantsArray[movingZombie.zombieRow][zombieColumn] = 0; //把植物移出数组
						plantContainer.removeChild(attackedPlant); //移出显示列表
					}
				}
			}
			//
			// 阳光管理
			//
			for (i = 0; i < sunContainer.numChildren; i++)
			{
				var fallingSun:sunMc = sunContainer.getChildAt(i) as sunMc;
				// 让我们看看阳光是否还在下落
				if (fallingSun.y < fallingSun.destinationY)
				{
					fallingSun.y++; // 把阳光往下移动一个像素
				}
				else
				{
					fallingSun.alpha -= 0.01; //  使阳光淡出
					// 检查阳光是否消失了
					if (fallingSun.alpha < 0)
					{
						fallingSun.removeEventListener(MouseEvent.CLICK, sunClicked); // 移除事件侦听from the sun
						sunContainer.removeChild(fallingSun); // 移出显示列表
					}
				}
			}
			//
			// 安置植物
			//
			if (playerMoving)
			{
				movingPlant.x = mouseX;
				movingPlant.y = mouseY;
				var plantRow:int = Math.floor((mouseY - 80) / 75);
				var plantCol:int = Math.floor((mouseX - 25) / 65);
				// 检查是否在游戏区域内
				if (plantRow >= 0 && plantCol >= 0 && plantRow < 5 && plantCol < 9)
				{
					selector.visible = true; // 显示选择器
					selector.x = 25 + plantCol * 65;
					selector.y = 80 + plantRow * 75;
				}
				else
				{
					selector.visible = false; // 隐藏选择器
				}
			}
		}
	}
}